#! /usr/bin/env python
# -*- coding: utf-8 -*-

from django.shortcuts import render, redirect
from django.http import JsonResponse
from web.form.issues import IssuesModelForm, IssuesReplyModelForm
from web import models
from utils.pagination import Pagination
from django.views.decorators.csrf import csrf_exempt
from django.utils.safestring import mark_safe
import json


class CheckFilter(object):
    def __init__(self, name, data_list, request):
        self.name = name
        self.data_list = data_list
        self.request = request

    def __iter__(self):
        for item in self.data_list:
            key = str(item[0])
            text = item[1]
            ck = ""
            # 如果当前用户请求的URL中status和当前循环key相等
            value_list = self.request.GET.getlist(self.name)
            if key in value_list:
                ck = 'checked'
                value_list.remove(key)
            else:
                value_list.append(key)

            # 为自己生成URL
            # 在当前URL的基础上去增加一项
            # status=1&age=19
            from django.http import QueryDict
            query_dict = self.request.GET.copy()
            query_dict._mutable = True
            query_dict.setlist(self.name, value_list)
            if 'page' in query_dict:
                query_dict.pop('page')

            param_url = query_dict.urlencode()
            if param_url:
                url = "{}?{}".format(self.request.path_info, param_url)  # status=1&status=2&status=3&xx=1
            else:
                url = self.request.path_info

            tpl = '<a class="cell" href="{url}"><input type="checkbox" {ck} /><label>{text}</label></a>'
            html = tpl.format(url=url, ck=ck, text=text)
            yield mark_safe(html)


class SelectFilter(object):
    def __init__(self, name, data_list, request):
        self.name = name
        self.data_list = data_list
        self.request = request

    def __iter__(self):
        yield mark_safe("<select class='select2' multiple='multiple' style='width:100%;' >")
        for item in self.data_list:
            key = str(item[0])
            text = item[1]

            selected = ""
            value_list = self.request.GET.getlist(self.name)
            if key in value_list:
                selected = 'selected'
                value_list.remove(key)
            else:
                value_list.append(key)

            query_dict = self.request.GET.copy()
            query_dict._mutable = True
            query_dict.setlist(self.name, value_list)
            if 'page' in query_dict:
                query_dict.pop('page')

            param_url = query_dict.urlencode()
            if param_url:
                url = "{}?{}".format(self.request.path_info, param_url)  # status=1&status=2&status=3&xx=1
            else:
                url = self.request.path_info

            html = "<option value='{url}' {selected} >{text}</option>".format(url=url, selected=selected, text=text)
            yield mark_safe(html)
        yield mark_safe("</select>")


def issues(request, project_id):
    if request.method == "GET":

        # 筛选条件
        allow_fillter_name = ['issue_type', 'status', 'priority']
        # ?status=1&status=2&issues_type=1
        condition = {}
        for name in allow_fillter_name:
            value_list = request.GET.getlist(name)
            if not value_list:
                continue
            condition[f'{name}__in'] = value_list

        # 分页获取数据
        qurey_set = models.Issues.objects.filter(project=request.tracer.project).filter(**condition)

        page_obj = Pagination(
            current_page=request.GET.get('page'),
            all_count=qurey_set.count(),
            base_url=request.path_info,
            query_params=request.GET,
            per_page=15
        )

        issues_list = qurey_set[page_obj.start: page_obj.end]
        form = IssuesModelForm(request)

        project_issues_type = models.IssuesType.objects.filter(project_id=project_id).values_list('id', 'title')

        project_total_user = [(request.tracer.project.creator_id, request.tracer.project.creator.username,)]
        join_user = models.ProjectUser.objects.filter(project_id=project_id).values_list('user_id', 'user__username')
        project_total_user.extend(join_user)

        context = {
            'form': form,
            'issues_list': issues_list,
            'page_html': page_obj.page_html(),
            'filter_list': [
                {'title': "问题类型", 'filter': CheckFilter('issue_type', project_issues_type, request)},
                {'title': "状态", 'filter': CheckFilter('status', models.Issues.status_choices, request)},
                {'title': "优先级", 'filter': CheckFilter('priority', models.Issues.priority_choices, request)},
                {'title': "指派者", 'filter': SelectFilter('assign', project_total_user, request)},
                {'title': "关注者", 'filter': SelectFilter('attention', project_total_user, request)},
            ]
        }
        return render(request, 'issues.html', context)

    if request.method == "POST":
        form = IssuesModelForm(request, data=request.POST)

        if form.is_valid():
            # 添加问题
            form.instance.project = request.tracer.project
            form.instance.creator = request.tracer.user
            form.save()
            return JsonResponse({'status': True})

        return JsonResponse({'status': False, 'error': form.errors})


def detail(request, project_id, issues_id):
    """编辑问题"""
    issues_obj = models.Issues.objects.filter(id=issues_id, project_id=project_id).first()
    form = IssuesModelForm(request, instance=issues_obj)

    return render(request, 'issues_detail.html', {'form': form, 'issues_obj': issues_obj})

@csrf_exempt
def issues_record(request, project_id, issues_id):
    """ 操作记录 """

    if request.method == "GET":
        reply_list = models.IssuseReply.objects.filter(issues_id=issues_id, issues__project=request.tracer.project)

        # 将querry set 转json
        data_list = []

        for row in reply_list:
            data = {
                'id': row.id,
                'reply_type_text': row.get_reply_type_display(),
                'content': row.content,
                'creator': row.creator.username,
                'datetime': row.create_datetime.strftime("%Y-%m-%d %H:%M:%S"),
                'parent_id': row.reply_id
            }
            data_list.append(data)

        return JsonResponse({'status': True, 'data': data_list})

    if request.method == "POST":
        form = IssuesReplyModelForm(data=request.POST)

        if form.is_valid():
            form.instance.issues_id = issues_id
            form.instance.reply_type = 2
            form.instance.creator = request.tracer.user

            instance = form.save()

            info = {
                'id': instance.id,
                'reply_type_text': instance.get_reply_type_display(),
                'content': instance.content,
                'creator': instance.creator.username,
                'datetime': instance.create_datetime.strftime("%Y-%m-%d %H:%M:%S"),
                'parent_id': instance.reply_id
            }
            return JsonResponse({'status': True, 'data': info})

        return JsonResponse({'status': False, 'error': form.errors})


@csrf_exempt
def issues_change(request, project_id, issues_id):

    issues_obj = models.Issues.objects.filter(id=issues_id, project_id=project_id).first()

    post_dict = json.loads(request.body.decode('utf-8'))

    name = post_dict.get('name')
    value = post_dict.get('value')
    field_obj = models.Issues._meta.get_field(name)

    def create_reply_record():
        new_instance = models.IssuseReply.objects.create(
            reply_type=1,
            issues=issues_obj,
            content=msg,
            creator=request.tracer.user
        )

        info = {
            'id': new_instance.id,
            'reply_type_text': new_instance.get_reply_type_display(),
            'content': new_instance.content,
            'creator': new_instance.creator.username,
            'datetime': new_instance.create_datetime.strftime("%Y-%m-%d %H:%M:%S"),
            'parent_id': new_instance.reply_id
        }

        return info

    # print(post_dict)
    # 1. 数据库字段更新
    # 1.1 文本字段
    if name in ['subject', 'desc', 'start_date', 'end_date']:
        if value:
            setattr(issues_obj, name, value)
            issues_obj.save()
            # 记录 xx更新为了 value
            msg = f"{field_obj.verbose_name}变更为{value}"
        else:
            if field_obj.null:
                setattr(issues_obj, name, None)
                issues_obj.save()
                msg = f"{field_obj.verbose_name}变更为空"
                # 记录 xx 更新为了 空
            else:
                return JsonResponse({'status': False, 'error': "字段不能为空"})

        info = create_reply_record()
        return JsonResponse({'status': True, 'data': info})

    # 1.2 FK字段
    if name in ['issue_type', 'module', 'parent', 'assign']:
        msg = ''
        # 用户选择为空
        if not value:
            # 不允许为空
            if not field_obj.null:
                return JsonResponse({'status': False, 'error': "字段不能为空"})

            # 允许为空
            setattr(issues_obj, name, None)
            issues_obj.save()
            msg = f"{field_obj.verbose_name}变更为空"
            # 记录 xx 更新为了 空
        else:  # 用户输入不为空
            # 判断用户输入的值是自己的值
            if name == 'assign':
                # 是否是创建者
                if value == str(request.tracer.project.creator_id):
                    instance = request.tracer.project.creator
                # 是否是参与者
                else:
                    project_user_obj = models.ProjectUser.objects.filter(project_id=project_id, user_id=value).first()
                    if project_user_obj:
                        instance = project_user_obj.user
                    else:
                        return JsonResponse({'status': False, 'error': "选择的值不存在"})
                setattr(issues_obj, name, instance)
                issues_obj.save()
                msg = f"{field_obj.verbose_name}变更为{str(instance)}"
            else:
                instance = field_obj.rel.model.objects.filter(id=value, project_id=project_id).first()
                if not instance:
                    return JsonResponse({'status': False, 'error': "选择的值不存在"})

                setattr(issues_obj, name, instance)
                issues_obj.save()
                msg = f"{field_obj.verbose_name}变更为{str(instance)}"

        info = create_reply_record()
        return JsonResponse({'status': True, 'data': info})

    # 1.3 choices字段
    if name in ['priority', 'status', 'mode']:
        selected_choices = None
        for key, text in field_obj.choices:
            if str(key) == value:
                selected_choices = text
        if not selected_choices:
            return JsonResponse({'status': False, 'error': "选择的值不存在"})

        setattr(issues_obj, name, value)
        issues_obj.save()
        msg = msg = f"{field_obj.verbose_name}变更为{selected_choices}"

        info = create_reply_record()
        return JsonResponse({'status': True, 'data': info})

    # 1.4 m2m 字段
    if name == 'attention':
        # list
        # {'name': attention, 'value': []}
        if not isinstance(value, list):
            return JsonResponse({'status': False, 'error': "数据格式错误"})

        if not value:
            issues_obj.attention.set([])
            issues_obj.save()
            msg = f"{field_obj.verbose_name}变更为空"
        else:
            # value 是否是项目成员
            # 当前项目所有成员
            user_dict = {str(request.tracer.project.creator_id): request.tracer.project.creator.username}
            project_user_list = models.ProjectUser.objects.filter(project_id=project_id)
            for i in project_user_list:
                user_dict[str(i.user_id)] = i.user.username

            username_list = []
            for u_id in value:
                username = user_dict.get(str(u_id))
                if not username:
                    return JsonResponse({'status': False, 'error': "用户不存在"})
                username_list.append(username)

            issues_obj.attention.set([])
            issues_obj.save()
            msg = f"{field_obj.verbose_name}变更为{','.join(username_list)}"

        info = create_reply_record()
        return JsonResponse({'status': True, 'data': info})
    # 2. 生成操作记录

    return JsonResponse({"status": False, 'error': "Unknown"})

